package com.jxpanda.spring.module.pay.core.pojo.wechat;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.jxpanda.infrastructure.core.tollkit.StringKit;
import com.wechat.pay.java.core.cipher.RSASigner;
import com.wechat.pay.java.core.util.NonceUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.util.Base64;

/**
 * @author Panda
 */
public class WechatPayResponse {

    @Data
    public static class UnifiedOrder {
        @JsonProperty("prepay_id")
        private String prepayId;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class SignatureData {
        private String prepayId;
        private String appId;
        private String timestamp;
        private String nonceStr;
        @JsonProperty("package")
        private String pack;
        private String signType;
        private String paySign;

        private SignatureData(String prepayId, String appId) {
            this.prepayId = prepayId;
            this.appId = appId;
            this.timestamp = Long.toString(System.currentTimeMillis() / 1000);
            this.nonceStr = NonceUtil.createNonce(32);
            this.pack = "prepay_id=" + prepayId;
            this.signType = "RSA";
            this.paySign = "";
        }

        private SignatureData signature(PrivateKey privateKey) {
            String signStr = this.appId + "\n"
                             + this.timestamp + "\n"
                             + this.nonceStr + "\n"
                             + this.pack + "\n";
            RSASigner rsaSigner = new RSASigner("",privateKey);
            String sign = rsaSigner.sign(signStr).getSign();
            this.paySign = Base64.getEncoder().encodeToString(sign.getBytes(StandardCharsets.UTF_8));
            return this;
        }

        private boolean isEffective() {
            return StringKit.isNotBlank(this.getPrepayId());
        }

        public static SignatureData signature(String prepayId, String appId, PrivateKey privateKey) {
            return new SignatureData(prepayId, appId).signature(privateKey);
        }

        public static SignatureData empty() {
            return new SignatureData();
        }

    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Refund {
        @JsonProperty("refund_id")
        private String refundId;
        @JsonProperty("transaction_id")
        private String transactionId;
        @JsonProperty("out_trade_no")
        private String outTradeNo;
        @JsonProperty("out_refund_no")
        private String outRefundNo;
        @JsonProperty("channel")
        private Channel channel;
        @JsonProperty("user_received_account")
        private String userReceivedAccount;
        @JsonProperty("success_time")
        private String successTime;
        @JsonProperty("create_time")
        private String createTime;
        @JsonProperty("status")
        private Status status;
        @JsonProperty("funds_account")
        private FundsAccount fundsAccount;
        @JsonProperty("amount")
        private WechatPayAmount amount;

        /**
         * 微信退款渠道枚举值
         */
        public enum Channel {
            /**
             * 原路退款
             */
            ORIGINAL,
            /**
             * 退回到余额
             */
            BALANCE,
            /**
             * 原账户异常退到其他余额账户
             */
            OTHER_BALANCE,
            /**
             * 原银行卡异常退到其他银行卡
             */
            OTHER_BANKCARD;
        }

        /**
         * 微信退款状态枚举
         */
        public enum Status {
            /**
             * 退款成功
             */
            SUCCESS,
            /**
             * 退款关闭
             */
            CLOSED,
            /**
             * 退款处理中
             */
            PROCESSING,
            /**
             * 退款异常
             */
            ABNORMA;
        }

        public enum FundsAccount {
            /**
             * 未结算资金
             */
            UNSETTLED,
            /**
             * 可用余额
             */
            AVAILABLE,
            /**
             * 不可用余额
             */
            UNAVAILABLE,
            /**
             * 运营户
             */
            OPERATION,
            /**
             * 基本账户（含可用余额和不可用余额）
             */
            BASIC;
        }

    }


    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Callback {
        @JsonProperty("code")
        private String code;
        @JsonProperty("message")
        private String message;

        public static Callback success() {
            return new Callback("SUCCESS", "成功");
        }

        public static Callback failed() {
            return new Callback("FAILED", "失败");
        }

    }


}
